﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Collections;

namespace CIRDiagnoseDevice
{
    public partial class TaxForm : Form
    {
        public TaxForm()
        {
            InitializeComponent();
        }
        #region 变量
        public int TrainTypeValue; //本/补、客/货值
        public byte DeviceStatus; //装置状态
        private int timeCul; //一秒计时计数
        private int TextFram; //显示多少帧数据
       SerialPort OSP = new  SerialPort();
       public static int TrainNum; //车次号保存
       public static string TrainType;//车次种类
        public static string CabNO;//机车号保存
        #endregion

        private void timer1_Tick(object sender, EventArgs e)
        {
            timeCul++;
            if (timeCul == 5)
            {
                timeCul = 0;
                SysTime.Text = System.DateTime.Now.ToString();
            }
            if (checkBox3.Checked)
            {
                if (OSP.IsOpen)
                {
                    byte[] sendData = SendDigData();
                    DispSendData(sendData);
                       OSP.Write(sendData, 0, sendData.Length);
                  
                }
            }
            else
            {
                if (OSP.IsOpen)
                {
                    byte[] sendData = SendAnalData();
                    OSP.Write(sendData, 0, sendData.Length);
                    DispSendData(sendData);
                }
            }
        }

        private void DispSendData(byte[] sendData)
        {
            string sb = string.Empty;
            for (int i = 0; i < sendData.Length; i++)
            {
                sb += (sendData[i].ToString("x2") + " ");
            }
            textBox1.AppendText(sb);
            textBox1.AppendText("\r\n\r\n");
            TextFram++;
            if (TextFram == 40)
            {
                TextFram = 0;
                textBox1.Clear() ;
            }
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            try
            {
                OSP.PortName = comboBox1.Text;
                OSP.BaudRate = 9600;
                OSP.DataBits = 8;
                OSP.StopBits = StopBits.One;
                button6.Enabled = true;
                button7.Enabled = true;
            }
            catch
            {

            }
        }

        private void TaxForm_Load(object sender, EventArgs e)
        {
            comboBox2.SelectedIndex = 0;
            comboBox1.Items.AddRange(SerialPort.GetPortNames());
            radioButton1.Checked = true;
            radioButton3.Checked = true;
            checkBox1.Checked = true;
            try
            {
                OSP.PortName = comboBox1.Text;
                OSP.BaudRate = 9600;
                OSP.DataBits = 8;
                OSP.StopBits = StopBits.One;
                OSP.Open();
                if (OSP.IsOpen)
                {
                    button6.Enabled = true;
                    button7.Enabled = true;
                    //button6.PerformClick();
                }
            }
            catch
            {

            }
            //GetDigFrameData();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked == true)
            {
                checkBox1.Text = "监控状态";
               // DeviceStatus = (byte)(DeviceStatus & 0x02);
            }
            else
            {
                checkBox1.Text = "降级状态";
               // DeviceStatus = (byte)(DeviceStatus | 0x01);
            }
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked == true)
            {
                checkBox2.Text = "非调车";
              //  DeviceStatus = (byte)(DeviceStatus & 0x01);
            }
            else
            {
                checkBox2.Text = "调车";
               // DeviceStatus = (byte)(DeviceStatus | 0x02);
            }
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox3.Checked == true)
            {
                checkBox3.Text = "数字信号";
                checkBox4.Enabled = false;
            }
            else
            {
                checkBox3.Text = "模拟信号";
                checkBox4.Enabled = true;
            }
        }

        private byte[] GetDigFrameData()
        {
            byte[] temp = new byte[82];
            temp[0] = 0x00;//信息长度2字节
            temp[1] = 0x50;
            temp[2] = 0x11;//源端口代码
            temp[3] = 0x00;//源地址长度
            temp[4] = 0x01;//目的端口代码
            temp[5] = 0x00;  // 目的地址长度
            temp[6] = 0x05;      //业务类型  
            temp[7] = 0x21;       //命令
            temp[8] = 0x38;     //本板地址
            temp[9] = 0x00;      //特征码
            temp[10] = 0x67;    //标志
            temp[11] = 0x01;   // 版本号
            temp[12] = 0x00;  // 保留字节
            temp[13] = 0x00;    //车站号
            if (textBox2.Text != "")
            {
               // int trainTypeFlag;
                string stri = textBox2.Text;//.ToUpper();
                TrainType = stri;
                byte[] trainTypeFlag = System.Text.ASCIIEncoding.Default.GetBytes(stri);
                for (int i = 0; i < 4; i++)
                {
                    if (i < 4 - stri.Length)
                    {
                        temp[14 + i] = 0x20;
                    }
                    else
                    {
                        temp[14 + i] = trainTypeFlag[i +  stri.Length -4];
                    }
                }
            }
            else
            {
                temp[14] = 0x20;    //车次种类标识符4字节
                temp[15] = 0x20;
                temp[16] = 0x20;
                temp[17] = 0x20;
                TrainType = "";
            }
            temp[18] = 0x00;    //司机号扩充字节
            temp[19] = 0x00;    //副司机号扩充字节
            temp[20] = 0x00;    //保留2 字节
            temp[21] = 0x00;
            temp[22] = 0x00;     // 机车型号扩充字节
            int teData;
             int.TryParse(textBox9.Text,out teData);
             temp[23] = (byte)teData;      //实际交路号
             for (int i = 0; i < 11; i++)
             {
                 temp[24 + i] = 0x00;          // 保留11字节
             }
             temp[35] = (byte)TrainTypeValue;  // 本/补、客/货
            int trainNum ;
            int.TryParse(textBox3.Text,out trainNum);
            TrainNum = trainNum;
            temp[36] = (byte)trainNum; //车次数字部分3字节
            temp[37] = (byte)(trainNum >> 8);
            temp[38] = (byte)(trainNum >> 16);
            byte check1 = 0;
            for (int i = 8; i < 39; i++)
            {
                check1 += temp[i];
            }
            check1 = (byte) ((check1 ^ 0xff) +1);
            temp[39] = check1;  // 检查和1
            temp[40] = 0x39;     //本板地址
            temp[41] = 0x30;      //特征码，30表示上次接收成功，c0表示上次接收失败
            temp[42] = 0x04;     // 检测单元代号
            DateTime time = System.DateTime.Now;
            uint intTime = toint(time);
            temp[43] = (byte)intTime; //时间4字节从年到秒
            temp[44] = (byte)(intTime >> 8);
            temp[45] = (byte)(intTime >> 16);
            temp[46] = (byte)(intTime >> 24);
            ushort speed ;
           ushort.TryParse(textBox15.Text,out speed);
            temp[47] = (byte)speed;  // 列车实速3字节
            temp[48] = (byte)(speed >> 8);
            temp[49] = 0x00;
            temp[50] = 0x01;    //机车信号
            temp[51] = 0x01;    //机车式况
            ushort signallor;
            ushort.TryParse(textBox13.Text,out signallor);
            temp[52] = (byte)signallor;         //信号机编号2字节
            temp[53] = (byte)(signallor >> 8);
            temp[54] = (byte)(comboBox2.SelectedIndex + 2);  // 33 信号机种类
            uint kilometer_post;
            uint.TryParse(textBox14.Text, out kilometer_post); 
            temp[55] = (byte)kilometer_post; // 34 公里标3字节
            temp[56] = (byte)(kilometer_post >> 8);
            temp[57] = (byte)(kilometer_post >> 16);
            ushort trainHeight ;                      //车重
            ushort.TryParse(textBox4.Text, out trainHeight);
            temp[58] = (byte)trainHeight;
            temp[59] = (byte)(trainHeight >> 8);
            ushort trainLength ;
            ushort.TryParse(textBox5.Text,out trainLength);   // 车长
            temp[60] = (byte)trainLength;
            temp[61] = (byte)(trainLength >> 8);
            byte railwayNum;
            byte.TryParse(textBox6.Text, out railwayNum);  
            temp[62] = railwayNum;      
            temp[63] = (byte)TrainTypeValue;
            temp[64] =(byte)(trainNum >> 8);
            temp[65] = (byte)trainNum;
            byte sectionNum ;
            byte.TryParse(textBox9.Text,out sectionNum);
            temp[66] = sectionNum;
            byte stationNum;
            byte.TryParse(textBox12.Text, out stationNum);
            temp[67] = stationNum;
            ushort driverNum;
            ushort.TryParse(textBox10.Text, out driverNum);
            temp[68] = (byte)driverNum;
            temp[69] = (byte)(driverNum >> 8);
            ushort viDrivNum;
            ushort.TryParse(textBox11.Text, out viDrivNum);
            temp[70] = (byte)viDrivNum;
            temp[71] = (byte)(viDrivNum >> 8);
            ushort trainNO;
            ushort.TryParse(textBox7.Text, out trainNO); // 机车号
            temp[72] = (byte)trainNO;
            temp[73] = (byte)(trainNO >> 8);
            byte trainType;
            byte.TryParse(textBox8.Text, out trainType);//机车型号
            CabNO = textBox8.Text + textBox7.Text;
            temp[74] = trainType;
            temp[75] = 0x58;
            temp[76] = 0x02;
            if (checkBox1.Checked)
            {
                if (checkBox2.Checked)
                {
                    DeviceStatus = 0x00;
                }
                else
                    DeviceStatus = 0x04;
            }
            else
            {
                if (checkBox2.Checked)
                {
                    DeviceStatus = 0x01;
                }
                else
                {
                    DeviceStatus = 0x05;
                }
            }
            temp[77] = DeviceStatus;
            temp[78] = 0x00;
            byte check2 =0x00;
            for (int j = 40; j < 79; j++)
            {
                check2 += temp[j];
            }
            temp[79] = (byte) (( check2^0xff) +1);  //二进制补码
            ushort checkSum = crc_16.CalculateCRC(temp, 0, (ushort)80);
            temp[80] =(byte)(checkSum >> 8) ;
            temp[81] = (byte)checkSum;
            return temp;
        }

        public byte[] SendDigData()
        {
            ArrayList sendData = new ArrayList();
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x02);
            byte[] frameData = GetDigFrameData();
            byte[] packetData = PacketData(frameData);
            for (int i = 0; i < packetData.Length; i++)
            {
                sendData.Add(packetData[i]);
            }
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x03);
            byte[] sendArray = new byte[sendData.Count];
            sendData.CopyTo(sendArray);
            return sendArray;
        }

        private byte[] GetAnalFrameDate()
        {
            byte[] temp = new byte[56];
            long bit_sync = 0xfffffffffffff;
            long bit_excl = 0x01;
            for (int i = 0; i < 26; i++)
            {
                bit_sync = (bit_sync ^ (bit_excl << 2 *i));
            }
            temp[0] = (byte)bit_sync;  //位同步
            temp[1] = (byte)(bit_sync >> 8);
            temp[2] = (byte)(bit_sync >> 16);
            temp[3] = (byte)(bit_sync >> 24);
            temp[4] = (byte)(bit_sync >> 32);
            temp[5] = (byte)(bit_sync >> 40);
            temp[6] =(byte) ((byte)(bit_sync >> 48) &0x03);
            int frame_sync =  0x0DD4259F;  //帧同步
            temp[7] = (byte)frame_sync;
            temp[8] = (byte)(frame_sync >> 8);
            temp[9] = (byte)(frame_sync >> 16);
            temp[10] = (byte)(frame_sync >> 24);
            temp[11] = 0x0c;
            temp[12] = 0x2b;
            temp[13] = 0x00;  //地址5字节
            temp[14] = 0x00;
            temp[15] = 0x1f;
            temp[16] = 0x3f;
            temp[17] = 0x00;
            temp[18] = 0xff;//控制字
            temp[19] = 0xff;//命令字
            temp[20] = 0xff;//信息功能码
            temp[21] = 0x20;//信息长度
            temp[22] = 0x01;// TDCS信号机
            temp[23] =(byte)(comboBox2.SelectedIndex + 2);
            temp[24] = (byte)TrainTypeValue;
            int trainTypeFlag;
            int.TryParse(textBox2.Text, out trainTypeFlag);
            temp[25] = (byte)trainTypeFlag;//车次种类标识符
            temp[26] = (byte)(trainTypeFlag >> 8);
            temp[27] = (byte)(trainTypeFlag >> 16);
            temp[28] = (byte)(trainTypeFlag >> 24);
            int trainNum;
            int.TryParse(textBox3.Text, out trainNum);
            temp[29] = (byte)trainNum;//车次数字部分
            temp[30] = (byte)(trainNum >> 8);
            temp[31] = (byte)(trainNum >> 16);
            byte trainType;
            byte.TryParse(textBox8.Text, out trainType);//机车类型
            temp[32] = trainType;
            temp[33] = 0x00;//机车类型扩充字节
            ushort trainNO;
            ushort.TryParse(textBox7.Text,out trainNO);
            temp[34] = (byte)trainNO; //机车号2字节
            temp[35] = (byte)(trainNO >> 8);
            temp[36] = 0x98;//公里标3字节
            temp[37] = 0x96;
            temp[38] = 0x10;
            uint speed;
            uint.TryParse(textBox15.Text, out speed);
            temp[39] = (byte)speed;//车速3字节
            temp[40] = (byte)(speed >> 8);
            temp[41] = (byte)(speed >> 16);
            ushort trainHeigt;
            ushort.TryParse(textBox4.Text,out trainHeigt);
            temp[42] = (byte) trainHeigt;//列车总重
            temp[43] = (byte)(trainHeigt>>8);
            ushort trainLength;
            ushort.TryParse(textBox5.Text, out trainLength);
            temp[44] = (byte)trainLength;//列车计长
            temp[45] = (byte)(trainLength >> 8);
            byte railwayNum;
            byte.TryParse(textBox6.Text, out railwayNum);
            temp[46] = railwayNum;
            byte stationNum;
            byte.TryParse(textBox12.Text, out stationNum);
            temp[47] = stationNum;
            temp[48] = 0x00;//车站号扩充字节
            byte sectionNum;
            byte.TryParse(textBox9.Text, out sectionNum);
            temp[49] = sectionNum;//交路号
            temp[50] = temp[48];//实际交路号
            ushort driverNum;
            ushort.TryParse(textBox10.Text,out driverNum);
            temp[51] = (byte)driverNum; // 司机号
            temp[52] = (byte)(driverNum >> 8);
            temp[53] = 0x00;// 司机扩充号
            ushort checkSum = 0;
            checkSum = crc_16.CalculateCRC(temp, 2, 51);
            temp[54] = (byte)checkSum;
            temp[55] = (byte)(checkSum >> 8);
            return temp;
        }

        public byte[] SendAnalData()
        {
            ArrayList sendData = new ArrayList();
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x02);
            byte[] frameData = GetAnalFrameDate();
            byte[] packegeData = PacketData(frameData);
            for (int i = 0; i < packegeData.Length; i++)
            {
                sendData.Add(packegeData[i]);
            }
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x03);
            byte[] sendArray = new byte[sendData.Count];
            sendData.CopyTo(sendArray);
            return sendArray;
        }

        private byte[] GetUnreadAnalData()
        {
            byte[] temp = new byte[55];
            long bit_sync = 0xfffffffffffff;
            long bit_excl = 0x01;
            for (int i = 0; i < 26; i++)
            {
                bit_sync = (bit_sync ^ (bit_excl << 2 * i));
            }
            temp[0] = (byte)bit_sync;  //位同步
            temp[1] = (byte)(bit_sync >> 8);
            temp[2] = (byte)(bit_sync >> 16);
            temp[3] = (byte)(bit_sync >> 24);
            temp[4] = (byte)(bit_sync >> 32);
            temp[5] = (byte)(bit_sync >> 40);
            temp[6] = (byte)((byte)(bit_sync >> 48) & 0x03);
            int frame_sync = 0x0DD4259F;  //帧同步
            temp[7] = (byte)frame_sync;
            temp[8] = (byte)(frame_sync >> 8);
            temp[9] = (byte)(frame_sync >> 16);
            temp[10] = 0x0c;   //3 模式字
            temp[11] = 0x2b;  // 4 数据长度
            temp[12] = 0x00;  // 5 地址5字节
            temp[13] = 0x00;
            temp[14] = 0x1f;
            temp[15] = 0x3f;
            temp[16] = 0x00;
            temp[17] = 0xff;//控制字
            temp[18] = 0xff;//命令字
            temp[19] = 0xff;//信息功能码
            temp[20] = 0x20;//信息长度
            temp[21] = 0x01;// TDCS信号机
            temp[22] =0x01;  // 信号机种类
            temp[23] =0x04;  // 本/补、客货
            temp[24] = 0x20;//车次种类标识符
            temp[25] = 0x20;
            temp[26] = 0x20;
            temp[27] = 0x20;
            temp[28] =  0x97;//车次数字部分
            temp[29] = 0x86;
            temp[30] = 0x01;
            temp[31] = 0xd3;           //机车类型
            temp[32] = 0x00;//机车类型扩充字节
            temp[33] = 0x12; //机车号2字节
            temp[34] = 0x13;
            temp[35] = 0x38;//公里标3字节
            temp[36] = 0xa2;
            temp[37] = 0x87;
            temp[38] = 0x3c;//车速3字节
            temp[39] =0x00;
            temp[40] =0x00 ;
            temp[41] = 0x00;//列车总重
            temp[42] = 0x00;
            temp[43] = 0x34;//列车计长
            temp[44] =0x02;
            temp[45] = 0x24;  //车厢数
            temp[46] = 0x01;  //车站号
            temp[47] = 0x00;  //车站号扩充字节
            temp[48] = 0x00;  //交路号
            temp[49] = temp[48];//实际交路号
            temp[50] =0x12; // 司机号
            temp[51] =0x00;
            temp[52] = 0x00;// 司机扩充号
            ushort checkSum = 0;
            checkSum = crc_16.CalculateCRC(temp, 2, (ushort)51);
            temp[53] = (byte)checkSum;
            temp[54] = (byte)(checkSum >> 8);
            return temp;
        }

        public byte[] SendUnreadAnalData()
        {
            ArrayList sendedData = new ArrayList();
            sendedData.Add(0x10);
            sendedData.Add(0x02);
            byte[] frameData = GetUnreadAnalData();
            byte[] packetedData = PacketData(frameData);
            for (int i = 0; i < packetedData.Length; i++)
            {
                sendedData.Add(packetedData[i]);
            }
            sendedData.Add(0x10);
            sendedData.Add(0x03);
            byte[] sendArray = new byte[sendedData.Count];
            sendedData.CopyTo(sendArray);
            return sendArray;
        }

        private byte[] PacketData(byte[] data)
        {
            ArrayList packetedData = new ArrayList();
            
            for (int i = 0; i < data.Length; i++)
            {
                packetedData.Add(data[i]);
                if (data[i] == 0x10)
                {
                    packetedData.Add(data[i]);
                }
              
            }
            //byte[] packegeArray = new byte[packetedData.Count+1];
            
            return (byte[])(packetedData.ToArray(typeof(byte)));
        }
        public static uint toint(DateTime dt)
        {
            uint x = 0;
            x += (uint)(dt.Year - 2000) << 26;
            x += (uint)dt.Month << 22;
            x += (uint)dt.Day << 17;
            x += (uint)dt.Hour << 12;
            x += (uint)dt.Minute << 6;
            x += (uint)dt.Second;
            return x;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox15.Text = "80";
            textBox9.Text = (int.Parse(textBox9.Text) +1).ToString();
            textBox13.Text = (int.Parse(textBox13.Text) + 1).ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBox15.Text = "20";
            textBox13.Text = (int.Parse(textBox13.Text) + 1).ToString();
            comboBox2.SelectedIndex = 1;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox15.Text = "60";
            comboBox2.SelectedIndex = 0;
            textBox13.Text = (int.Parse(textBox13.Text) + 1).ToString();
            Delay(300);
            comboBox2.SelectedIndex = 2;
        }

        //延时多少毫秒
        public static void Delay(int mSecond)
        {
            int last_start;

            last_start = Environment.TickCount;
            while ((Environment.TickCount - last_start) <= mSecond)
            {
                Application.DoEvents();
            }
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        //客/货选择
        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton3.Checked)
                     TrainTypeValue |= 0x01;                 
            else
                TrainTypeValue &= 0x02;   
               
        }

       //本/补机选择
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
                TrainTypeValue |= 0x00;
            else
                TrainTypeValue &= 0x01;
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox4.Checked)
            {
                checkBox4.Text = "不读取监测设备信息";
            }
            else
            {
                checkBox4.Text = "读取监测设备信息";
            }
        }

        private void TaxForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            OSP.Close();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                OSP.Open();
            }
            catch { }
            if (OSP.IsOpen)
            {
                comboBox1.Enabled = false;
                checkBox2.Enabled = false;
                button1.Enabled = true;
                button2.Enabled = true;
                button3.Enabled = true;
                button4.Enabled = true;
                button5.Enabled = true;
                timer1.Enabled = true;
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            OSP.Close();
            checkBox2.Enabled = true;
            button5.Enabled = false;
            button4.Enabled = false;
            button3.Enabled = false;
            button2.Enabled = false;
            button1.Enabled = false;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            button4.Enabled = false;
            textBox15.Text = "0";
            Delay(200);
            textBox15.Text = "1";
            Delay(200);
            textBox15.Text = "3";
            Delay(200);
            textBox15.Text = "5";
            button4.Enabled = true;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            button4.Enabled = false;
            textBox15.Text = "50";
            Delay(200);
            textBox15.Text = "30";
            Delay(200);
            textBox15.Text = "10";
            Delay(200);
            textBox15.Text = "0";
            Delay(6000);
            button4.Enabled = true;
        }
    }
}
